package cn.sunxyz.data.orm.impl;

import cn.sunxyz.data.db.DefaultSQLRunner;
import cn.sunxyz.data.db.SQLRunner;
import cn.sunxyz.data.orm.EntityQueryManger;
import cn.sunxyz.data.orm.IMethod;
import cn.sunxyz.data.orm.SQLManager;
import cn.sunxyz.data.orm.ex.EntityQueryException;
import cn.sunxyz.data.sample.test.JdbcUtils;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by yangrd on 2017/6/7.
 */
public class DefaultEntityQueryManger implements EntityQueryManger {

    private static Logger logger = LoggerFactory.getLogger(DefaultEntityQueryManger.class);

    private static DefaultEntityQueryManger defaultEntityQueryManger = new DefaultEntityQueryManger();

    private static SQLRunner sqlRunner = DefaultSQLRunner.getSingleton();

    private static SQLManager sqlManager = CacheSQLManager.getSingleton();

    public static DefaultEntityQueryManger getSingleton() {
        return defaultEntityQueryManger;
    }

    @Override
    public <T> List<T> queryList(IMethod iMethod, Object... params) {
        String sql = sqlManager.getSql(iMethod);
        return queryListBySql((Class<T>) iMethod.getTargetClazz(), sql, params);
    }

    @Override
    public <T> T query(IMethod iMethod, Object... params) {
        String sql = sqlManager.getSql(iMethod);
        return queryBySql((Class<T>) iMethod.getTargetClazz(), sql, params);
    }

    @Override
    public int delete(IMethod iMethod, Object... params) {
        String sql = sqlManager.getSql(iMethod);
        return update(sql, params);
    }

    @Override
    public int update(String sql, Object... params) {
        logger.debug("[] => {}", sql);
        try {
            return sqlRunner.update(getConnection(), sql, params);
        } catch (SQLException e) {
            throw new EntityQueryException(e.getMessage());
        }
    }

    private <T> T queryBySql(Class<T> cls, String sql, Object... params) {
        logger.debug("[] => {}", sql);
        try {
            return (T) sqlRunner.query(getConnection(), sql, new BeanHandler(cls), params);
        } catch (SQLException e) {
            throw new EntityQueryException(e.getMessage());
        }
    }

    private <T> List<T> queryListBySql(Class<T> cls, String sql, Object... params) {
        logger.debug("[] => {}", sql);
        try {
            return (List<T>) sqlRunner.query(getConnection(), sql, new BeanListHandler(cls), params);
        } catch (SQLException e) {
            throw new EntityQueryException(e.getMessage());
        }
    }


    //TODO 此处需要修改
    public Connection getConnection() {
        try {
            return JdbcUtils.getDataSource().getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
